<template>
	<div
		:class="[
			'app-editor-container',
			'app-mob-data-picker-view',
			`app-mob-data-picker-view-${name}`,
		]"
	>
		<van-field
			v-bind="$attrs"
			readonly
			:type="multiple ? 'textarea' : 'text'"
			:autosize="true"
			:center="true"
			v-model="curValue"
			:disabled="disabled"
			@click="setPopupState(true)"
		>
			<template #right-icon>
				<van-icon v-if="curValue" name="clear" @click="handleClear" />
				<van-icon name="arrow-down" />
			</template>
		</van-field>
		<van-popup
			v-model:show="popupState"
			round
			teleport="body"
			position="bottom"
			class="data-picker-view__popup"
		>
			<div class="popup__container">
				<div class="popup__header">
					<div @click="cancel" class="cancel">
						{{ $t('common.generic.onCancel', '取消') }}
					</div>
					<div @click="confirm" class="confirm">
						{{ $t('common.generic.okText', '确定') }}
					</div>
				</div>
				<div class="popup__content">
					<van-radio-group
						v-if="!multiple"
						v-bind="$attrs"
						class="dropdown-list__group"
						:disabled="disabled"
						v-model="selectedKeys[0]"
					>
						<van-cell-group>
							<van-cell
								v-for="(option, index) in options"
								clickable
								:key="index"
								:title="option[deMajorField]"
								@click="selectedKeys = [option.value]"
							>
								<template #right-icon>
									<van-radio
										class="app-mob-radio-list__item"
										:name="option.value"
										:disabled="option.disabled"
									></van-radio>
								</template>
							</van-cell>
						</van-cell-group>
					</van-radio-group>
					<van-checkbox-group
						v-else
						v-bind="$attrs"
						class="dropdown-list__group"
						v-model="selectedKeys"
					>
						<van-cell-group>
							<van-cell
								v-for="(item, index) in options"
								clickable
								:key="index"
								:title="item[deMajorField]"
								@click="toggle(index)"
							>
								<template #right-icon>
									<van-checkbox
										:key="index"
										:name="item.value"
										shape="square"
										:ref="(el) => (checkboxRefs[index] = el)"
										@click.stop
									/>
								</template>
							</van-cell>
						</van-cell-group>
					</van-checkbox-group>
				</div>
			</div>
		</van-popup>
	</div>
</template>
<script lang="ts" setup>
import { Ref } from 'vue';
import { deepCopy, IEvent, IParam } from '@/core';
import { dataPickerViewProps } from './data-picker-view';
import { handleEditorNavParams, useEditorTypeParams } from '@/hooks/use-editor';
interface EditorEmit {
	(name: 'editor-event', value: IEvent<string>): void;
}
const props = defineProps(dataPickerViewProps);
const emit = defineEmits<EditorEmit>();
// 类型校验
const {
	validateConfig,
	valueType,
	textSeparator,
	objectNameField,
	objectIdField,
	objectValueField,
} = useEditorTypeParams();
validateConfig();
const { navContext, navViewParam } = handleEditorNavParams(props);
const deMajorField: string = objectNameField
	? objectNameField
	: props.deMajorField;
const deKeyField: string = objectIdField ? objectIdField : props.deKeyField;
const options: Ref<any[]> = ref([]);

let isLoad = false;

/**
 * 多选checkbox的ref
 */
const checkboxRefs: Ref<any[]> = ref([]);

/**
 * 选中值key集合
 */
const selectedKeys: Ref<string[]> = ref([]);

/**
 * @description 复选框切换
 */
const toggle = (index: number) => {
	checkboxRefs.value[index].toggle();
};

const popupState = ref(false);

const curValue: Ref<any> = computed(() => {
	if (!props.value) {
		curValue.value = null;
		return null;
	} else {
		if (props.multiple) {
			try {
				if (valueType === 'OBJECTS') {
					return (props.value as [])
						.map((item: any) => {
							return item[props.deMajorField];
						})
						.join(textSeparator);
				}
				return JSON.parse(props.value as string)
					.map((item: any) => {
						return item[props.deMajorField];
					})
					.join(textSeparator);
			} catch (error) {
				return '';
			}
		} else {
			if (valueType === 'OBJECT') {
				return (props.value as any)[deMajorField];
			}
			return props.value;
		}
	}
});


//打开弹窗
const setPopupState = (state: boolean) => {
	if (!props.disabled) {
		popupState.value = state;
		if(isLoad == false){
			onSearch();
		}
	}
};
/**
 * @description 取消
 */
const cancel = () => {
	initSelectData();
	setPopupState(false);
};

/**
 * @description 初始化选中数据
 */
const initSelectData = () => {
	if (props.multiple) {
		if (Object.is(valueType, 'OBJECTS')) {
			selectedKeys.value = (props.value as [])?.map((item:any)=>{
					return item[deKeyField]
				}) || [];
		} else {
			try {
				selectedKeys.value = JSON.parse((props.value as string)).map((item:any)=>{
					return item[deKeyField]
				}) || [];
			} catch (error) {
				selectedKeys.value = [];
			}
		}
	} else {
		if(props.valueItem){
			selectedKeys.value = [props.data[props.valueItem]];
		}
	}
};

/**
 * @description 确定
 */
const confirm = () => {
	doEditorEmit();
	setPopupState(false);
};

//搜索数据
const onSearch = async (value: string = '') => {
	if (props.disabled) {
		return;
	}
	const _navContext = deepCopy(navContext);
	const _navViewParam = deepCopy(navViewParam);
	Object.assign(_navViewParam, { query: value, size: 1000 });
	const requestException: string = App.ts(
		'common.generic.requestexception',
		'请求异常'
	);
	if (!props.service) {
		console.warn(App.ts('common.generic.noservice', '服务不存在'));
	} else if (!props.acParams) {
		console.warn(App.ts('common.generic.miss', '参数不存在'));
	} else {
		const { serviceName, interfaceName } = props.acParams;
		const { deKeyField, deCodeName } = props;
		try {
			const response = await props.service.getItems(
				serviceName,
				interfaceName,
				_navContext,
				_navViewParam,
				deKeyField,
				deCodeName
			);
			if (!response) {
				console.warn(App.ts('common.generic.loadfail', '加载数据失败'));
				return;
			} else {
				isLoad = true;
				options.value = response;
			}
		} catch (error: any) {
			console.warn(
				error && error.message ? error.message : `代码表${requestException}`
			);
		}
	}
};

// 处理对象类型参数
const handleObjectParams = (item: IParam, otherParams: IParam): IParam => {
	const object: IParam = { ...otherParams };
	if (objectNameField) {
		Object.assign(object, {
			[objectNameField]: item[objectNameField],
		});
	}
	if (objectIdField) {
		Object.assign(object, {
			[objectIdField]: item[objectIdField],
		});
	}
	if (objectValueField) {
		Object.assign(object, {
			[objectValueField]: deepCopy(item),
		});
	}
	return object;
};

//统一抛值
const doEditorEmit = () => {
	let value: any;
	let keyValue: any;
	if (selectedKeys.value.length === 0) {
		value = null;
		keyValue = null;
	} else if (props.multiple) {
		const tempSelectArray: any = [];
		selectedKeys.value.forEach((key: any) => {
			const item = options.value.find((item: any) => {
				return item[props.deKeyField] === key;
			});
			if (item) {
				let selected = {
					[deMajorField]: item[deMajorField],
					[deKeyField]: item[deKeyField],
				};
				tempSelectArray.push(
					Object.is(valueType, 'OBJECTS')
						? handleObjectParams(item, selected)
						: selected
				);
			}
		});
		if (Object.is(valueType, 'OBJECTS')) {
			value = tempSelectArray;
		} else {
			value = JSON.stringify(tempSelectArray);
		}
	} else {
		const selectItem = options.value.find((item: any) => {
			return item[props.deKeyField] === selectedKeys.value[0];
		});
		if (!selectItem) {
			value = null;
			keyValue = null;
		}
		if (valueType === 'OBJECT') {
			value = handleObjectParams(selectItem, {
				[props.deMajorField]: selectItem[props.deMajorField],
			});
		} else {
			value = selectItem[props.deMajorField];
		}
		keyValue = selectedKeys.value[0];
	}
	if (props.valueItem) {
		emit('editor-event', {
			name: `${props.valueItem}`,
			action: 'valueChange',
			data: keyValue,
		});
	}
	emit('editor-event', {
		name: `${props.name}`,
		action: 'valueChange',
		data: value,
	});
};

//点击清除按钮
const handleClear = (event: any) => {
	event.preventDefault();
	event.stopPropagation();
	if (props.valueItem) {
		emit('editor-event', {
			name: `${props.valueItem}`,
			action: 'valueChange',
			data: null,
		});
	}
	emit('editor-event', {
		name: `${props.name}`,
		action: 'valueChange',
		data: null,
	});
};
</script>
